其他
Xposed第四课(微信篇) 朋友圈点赞 (1)
上篇文章有些小伙伴问我怎么去看布局文件的,我这里交代先我分析界面的方法
1、 adb shell dumpsys activity top
2、 as自带的layout inspector(有些情况无法得到绘制)
但是显示效果最好
3、 Android Device Monitor 相信以前用eclipse时候adt经常用到的
好了废话不多说了,以上是我用到的,如果有更好的可以给我留言
首先 terminal 输入 adb shell dumpsys activity top 如下
往下继续翻
然后咱们看看分析分析 SnsTimeLineUI 里面的代码逻辑
public void onCreate(Bundle bundle) {
...省略N多代码...
this.skT = this.rUA;
this.slh.a(this.sle, this.jzz, str, str2, this.slf, this.rWo, this.slg);
//这句话是初始化里面的列表等组建
this.slh.onCreate();
ae.byE().init();
this.mActionBar = getSupportActionBar();
com.tencent.mm.kernel.g.Ea();
com.tencent.mm.kernel.g.DX().fUP.a((int) com.tencent.mm.plugin.appbrand.jsapi.bio.face.c.CTRL_INDEX, (e) this);
com.tencent.mm.kernel.g.Ea();
com.tencent.mm.kernel.g.DX().fUP.a(682, (e) this);
com.tencent.mm.kernel.g.Ea();
com.tencent.mm.kernel.g.DX().fUP.a(218, (e) this);
...省略N多代码...
}
通过上面的代码可以找到
com.tencent.mm.plugin.sns.ui.bb
在这个文件里面就有我们刚才在terminal里面看到的很多关联的东西
所以关联起来可以开始编码了,里面注释的代码都是打印的关键信息,可以在一边调试一边看输出信息
/**
* hook 朋友圈
*
* @param applicationContext
* @param classLoader
*/
private void hookWxMoments(final Context applicationContext, final ClassLoader classLoader) throws Error {
XposedHelpers.findAndHookMethod("com.tencent.mm.plugin.sns.ui.bb",
classLoader,
"onCreate",
new XC_MethodHook() {
protected void afterHookedMethod(MethodHookParam param) throws Throwable {
super.afterHookedMethod(param);
Field mat = XposedHelpers.findFieldIfExists(param.thisObject.getClass(), "mActivity");
final Activity mActivity = (Activity) mat.get(param.thisObject);
Field odm = XposedHelpers.findFieldIfExists(param.thisObject.getClass(), "odm");
ListView mlv = (ListView) odm.get(param.thisObject);
Class<?> mlvSuperClass = mlv.getClass().getSuperclass();
// LogUtils.i(mlv.toString(), mlvSuperClass.toString());
XposedHelpers.findAndHookMethod(mlvSuperClass,
"setAdapter",
ListAdapter.class,
new XC_MethodHook() {
protected void beforeHookedMethod(MethodHookParam param) throws Throwable {
super.beforeHookedMethod(param);
final ListAdapter adapter = (ListAdapter) param.args[0];
// LogUtils.i(adapter.toString());
XposedHelpers.findAndHookMethod(adapter.getClass(),
"getView",
int.class,
View.class,
ViewGroup.class,
new XC_MethodHook() {
protected void beforeHookedMethod(MethodHookParam param) throws Throwable {
super.beforeHookedMethod(param);
// int position = (int) param.args[0];
final View view = (View) param.args[1];
// ViewGroup viewGroup = (ViewGroup) param.args[2];
if (view != null) {
//fl 第一个view是图片 第二个view是朋友圈内容
final ViewGroup fl = (ViewGroup) view;
// StringBuffer sb = new StringBuffer();
// for (int i = 0; i < fl.getChildCount(); i++) {
// sb.append(fl.getChildAt(i).toString());
// sb.append("@");
// sb.append(fl.getChildAt(i).getId());
// sb.append("@");
// sb.append(applicationContext.getResources().getResourceName(fl.getChildAt(i).getId()));
// sb.append("\n");
// }
// LogUtils.i(position, view, sb.toString(), viewGroup, JSON.toJSONString(adapter.getItem(position)), adapter.getItem(position).toString());
view.setOnLongClickListener(new View.OnLongClickListener() {
public boolean onLongClick(View v) {
new AlertDialog.Builder(mActivity)
.setTitle("温馨提示")
.setMessage("是否对当前消息进行疯狂点赞").setNegativeButton("是的", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
mActivity.runOnUiThread(new Runnable() {
public void run() {
if (fl != null && fl.getChildCount() > 1) {
LinearLayout msgLinear = (LinearLayout) fl.getChildAt(1);
for (int i = 0; i < msgLinear.getChildCount(); i++) {
View mc = msgLinear.getChildAt(i);
String resourceName = applicationContext.getResources().getResourceName(mc.getId());
if (mc instanceof TextView) {
// mc.setVisibility(View.VISIBLE);
// ((TextView) mc).append("看雪论坛,看雪论坛++,看雪论坛+++");
//因为有些gettext 得到的是spanned 调toString会引起shutdown 所以用以下方式打印即可
// LogUtils.i(((TextView) mc).getText());
} else if (mc instanceof ViewStub) {
// ((ViewStub) mc).inflate();
} else if("com.tencent.mm:id/de_".equals(resourceName)){
ViewGroup vg = (ViewGroup)mc;
mc.setVisibility(View.VISIBLE);
if(vg.getChildCount()>0){
TextView likeView = (TextView) vg.getChildAt(0);
likeView.append("看雪论坛,看雪论坛++,看雪论坛+++");
LogUtils.i(likeView.getCompoundDrawables());
}else {
TextView tv = new TextView(applicationContext);
tv.setText(",看雪论坛,看雪论坛++,看雪论坛+++");
tv.setLayoutParams(new LinearLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT));
vg.addView(tv);
}
}
// LogUtils.i(mc, resourceName, "com.tencent.mm:id/de_");
}
}
}
});
}
}).setNeutralButton("不是的", null).show();
return false;
}
});
}
}
});
}
});
}
});
}
最终结果 如下图
去掉上图代码注释效果图 | 去掉上图代码注释效果图 |
去掉注释我把所有view都展示出来了,后面过滤注释无用代码后只留下点赞栏目的view即可
这个只是做了ui效果,后面会进行数据库保存记录,保证下次浏览到该条信息能够直接显示点赞数据,并且尽可能实现从好友列表选择点赞人。
代码已上传(点击阅读原文,在原帖下载查看)
本文由看雪论坛 KingZd 原创
转载请注明来自看雪社区
往期热门阅读:
扫描二维码关注我们,更多干货等你来拿!